

fn leap(y: u32) -> bool {
    y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)
}

fn calc_year_days(y: u32) -> u32 {
    y * 365 + (y/4 - y/100 + y/400)
}

fn calc_month_days(m: u32, leap: bool) -> u32 {
    [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334][m as usize]
    + if leap && m >= 2 { 1 } else { 0 }
}

fn ymd_to_uniday(y: u32, m: u32, d: u32) -> u32 {
    calc_year_days(y-1) + calc_month_days(m-1, leap(y)) + d - 1
}

const CHINESE_NEW_YEAR_DATE: [u32; 170] = [31, 50, 39, 29, 47, 35, 25, 44, 33, 22, 41, 30, 49, 37, 26, 45, 34, 23, 42, 32, 51, 39, 28, 47, 36, 24, 44, 33, 23, 41, 30, 48, 37, 26, 45, 35, 24, 42, 31, 50, 39, 27, 46, 36, 25, 44, 33, 22, 41, 29, 48, 37, 27, 45, 34, 24, 43, 31, 49, 39, 28, 46, 35, 25, 44, 33, 21, 40, 30, 48, 37, 27, 46, 34, 23, 42, 31, 49, 38, 28, 47, 36, 25, 44, 33, 51, 40, 29, 48, 37, 27, 46, 35, 23, 41, 31, 50, 38, 28, 47, 36, 24, 43, 32, 22, 40, 29, 49, 38, 26, 45, 34, 23, 41, 31, 50, 39, 28, 47, 36, 25, 43, 32, 22, 41, 29, 48, 37, 26, 44, 34, 23, 42, 31, 50, 39, 28, 46, 35, 24, 43, 32, 22, 41, 30, 48, 37, 26, 45, 33, 23, 42, 32, 50, 39, 28, 46, 35, 24, 43, 33, 21, 40, 29, 48, 36, 26, 45, 34, 23,];

fn chinese_new_year_eve_uniday(y: u32) -> u32 {
    ymd_to_uniday(y, 1, 1) + if y < 1900 || y >= 2070 {
        0 // set default to
    } else {
        CHINESE_NEW_YEAR_DATE[(y - 1900) as usize] - 2
    }
}

fn calc_time_inner(y: u32, m: u32, d: u32) -> (u32, u32, u32) {

    let uniday_cur_day = ymd_to_uniday(y, m, d);
    // task1
    let uniday_cur_year_week1 = ymd_to_uniday(y, 1, 4);
    let uniday_nxt_year_week1 = ymd_to_uniday(y+1, 1, 4);
    let uniday_lst_year_week1 = ymd_to_uniday(y-1, 1, 4);
    let week_cnt = if uniday_cur_day / 7 == uniday_nxt_year_week1 / 7 {
            1
        } else if uniday_cur_day / 7 >= uniday_cur_year_week1 / 7 {
            uniday_cur_day / 7 - uniday_cur_year_week1 / 7 + 1
        } else {
            uniday_cur_day / 7 - uniday_lst_year_week1 / 7 + 1
        };
    // task2
    let uniday_year_end = ymd_to_uniday(y, 12, 31);
    let rest_day_cnt = uniday_year_end - uniday_cur_day;
    // task3
    let uniday_cur_chinese_new_year_eve = chinese_new_year_eve_uniday(y);
    let uniday_nxt_chinese_new_year_eve = chinese_new_year_eve_uniday(y+1);
    let rest_chinese_new_year_day_cnt = if uniday_cur_day <= uniday_cur_chinese_new_year_eve {
        uniday_cur_chinese_new_year_eve - uniday_cur_day
    } else {
        uniday_nxt_chinese_new_year_eve - uniday_cur_day
    };

    (week_cnt, rest_day_cnt, rest_chinese_new_year_day_cnt)
}

pub fn time_info(time: &str) -> String {
    let mut time = time.split('-');
    let y: u32 = time.next().unwrap().parse().unwrap();
    let m: u32 = time.next().unwrap().parse().unwrap();
    let d: u32 = time.next().unwrap().parse().unwrap();
    let (x, y, z) = calc_time_inner(y, m, d);
    format!("{x},{y},{z}")
}
